package cn.zzdt4j.config.springboot.starter.support;

import cn.hutool.core.util.BooleanUtil;
import cn.zzdt4j.common.executor.ThreadPoolExecutorRegistry;
import cn.zzdt4j.common.executor.support.BlockingQueueTypeEnum;
import cn.zzdt4j.common.executor.support.RejectedPolicyTypeEnum;
import cn.zzdt4j.common.model.excutor.ExecutorProperties;
import cn.zzdt4j.common.model.register.DynamicThreadPoolRegisterParameter;
import cn.zzdt4j.common.model.register.DynamicThreadPoolRegisterWrapper;
import cn.zzdt4j.common.model.register.notify.DynamicThreadPoolRegisterCoreNotifyParameter;
import cn.zzdt4j.core.executor.support.service.AbstractDynamicThreadPoolService;
import cn.zzdt4j.threadpool.message.core.service.GlobalNotifyAlarmManage;
import cn.zzdt4j.threadpool.message.core.service.ThreadPoolNotifyAlarm;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * Dynamic thread-pool config service.
 *
 * @author by <a href="mailto:ligang941012@gmail.com">gang.Li</a>
 * @since 2024/5/14 0:44
 */
public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolService {

    @Override
    public ThreadPoolExecutor registerDynamicThreadPool(DynamicThreadPoolRegisterWrapper registerWrapper) {
        DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getParameter();
        String threadPoolId = registerParameter.getThreadPoolId();
        ThreadPoolExecutor dynamicThreadPoolExecutor = buildDynamicThreadPoolExecutor(registerParameter);
        ExecutorProperties executorProperties = buildExecutorProperties(registerWrapper);
        ThreadPoolExecutorRegistry.putHolder(threadPoolId, dynamicThreadPoolExecutor, executorProperties);
        DynamicThreadPoolRegisterCoreNotifyParameter notifyParameter = registerWrapper.getConfigNotify();
        ThreadPoolNotifyAlarm notifyAlarm = new ThreadPoolNotifyAlarm(true, registerParameter.getActiveAlarm(), registerParameter.getCapacityAlarm());
        notifyAlarm.setReceives(notifyParameter.getReceives());
        notifyAlarm.setInterval(notifyParameter.getInterval());
        GlobalNotifyAlarmManage.put(threadPoolId, notifyAlarm);
        return dynamicThreadPoolExecutor;
    }

    private ExecutorProperties buildExecutorProperties(DynamicThreadPoolRegisterWrapper registerWrapper) {
        DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getParameter();
        return ExecutorProperties.builder()
                .corePoolSize(registerParameter.getCorePoolSize())
                .maximumPoolSize(registerParameter.getMaximumPoolSize())
                .allowCoreThreadTimeOut(BooleanUtil.toBoolean(String.valueOf(registerParameter.getAllowCoreThreadTimeOut())))
                .keepAliveTime(registerParameter.getKeepAliveTime())
                .blockingQueue(BlockingQueueTypeEnum.getBlockingQueueNameByType(registerParameter.getBlockingQueueType().getType()))
                .queueCapacity(registerParameter.getCapacity())
                .threadNamePrefix(registerParameter.getThreadNamePrefix())
                .rejectedHandler(RejectedPolicyTypeEnum.getRejectedNameByType(registerParameter.getRejectedPolicyType().getType()))
                .executeTimeOut(registerParameter.getExecuteTimeOut())
                .threadPoolId(registerParameter.getThreadPoolId())
                .build();
    }
}
